package hu.mapro.gwtui.gxt.client.ui;

import hu.mapro.gwtui.gxt.client.fieldseditor.InstanceFieldsEditor;
import hu.mapro.gwtui.gxt.client.fieldseditor.RequestContextInitializer;
import hu.mapro.gwtui.gxt.client.recordseditor.EditorProviderInterface;
import hu.mapro.gwtui.gxt.client.recordseditor.RecordsEditorBuilder;
import hu.mapro.gwtui.gxt.client.recordseditor.field.SortFieldAdapter;
import hu.mapro.gwtui.gxt.client.recordseditor.requestfactory.Interface;
import hu.mapro.gwtui.gxt.client.recordseditor.requestfactory.PersistenceAdapter;
import hu.mapro.model.Getter;
import hu.mapro.model.meta.Field;

import com.google.common.base.Function;
import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.sencha.gxt.data.shared.ModelKeyProvider;

public abstract class ComplexRecordsEditor<
	T extends BaseProxy, 
	F extends Field<T,?>&Getter<T, ? extends Comparable<?>>
	//RO extends Field<T,?>&HasLabel&Getter<T, ?>
> extends RecordsEditorBuilder<T, F, RequestContextInitializer> {
	
	//protected Builder<RO> tableColumns = ImmutableList.builder();
	
	protected Function<T, InstanceFieldsEditor<? extends T, RequestContextInitializer>> editorFunction;
	
	//protected hu.mapro.gwtui.gxt.client.recordseditor.EditorInterface<T> requestMethods;
	
	@Override
	public void build() {
		buildSortField();
		buildModelKeyProvider();
		buildMainInterface();
//		buildColumnModelProvider();
		
		setPersistenceInterface(new PersistenceAdapter<T>(createPersistenceAdapter()));
		
		super.build();
	}

	abstract protected Interface<T> createPersistenceAdapter();
	
//	protected void buildColumnModelProvider() {
//		setColumnModel(buildColumnModelBuilder());
//	}
//
//	protected hu.mapro.gwtui.gxt.client.columnmodel.ColumnModelProvider<T> buildColumnModelBuilder() {
//		hu.mapro.gwtui.gxt.client.columnmodel.Builder<T, RO, Void> builder = new hu.mapro.gwtui.gxt.client.columnmodel.Builder<T, RO, Void>(buildColumnReadOnly(), null);
//		builder.readOnly(tableColumns.build());
//		return builder;
//	}

//	private ReadOnlyInterface<T, RO> buildColumnReadOnly() {
//		return new ReadOnlyAdapter<T, RO>();
//	}

	protected void buildMainInterface() {
		setEditorInterface(new EditorProviderInterface<T, RequestContextInitializer>() {
			@SuppressWarnings("unchecked")
			@Override
			public <V extends T> InstanceFieldsEditor<V, RequestContextInitializer> edit(
					V object) {
				return (InstanceFieldsEditor<V, RequestContextInitializer>) editorFunction.apply(object);
			}
		});
		
	}

	protected void buildModelKeyProvider() {
		setModelKeyProvider(createModelKeyAdapter());
	}

	abstract protected ModelKeyProvider<? super T> createModelKeyAdapter();

	protected void buildSortField() {
		setSortFieldInterface(new SortFieldAdapter<T, F>());
	}

//	public void setTableColumns(RO[] tableColumns) {
//		clearTableColumns();
//		this.tableColumns.add(tableColumns);
//	}
//
//	protected void clearTableColumns() {
//		this.tableColumns = ImmutableList.builder();
//	}

	public void setEditorFunction(
			Function<T, InstanceFieldsEditor<? extends T, RequestContextInitializer>> editorFunction) {
		this.editorFunction = editorFunction;
	}

//	public Builder<RO> getTableColumns() {
//		return tableColumns;
//	}

}
